package com.zephyr.vchcenter.util;

import java.sql.Blob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.hibernate.Hibernate;

import com.zephyr.vchcenter.bean.ResultImage;
import com.zephyr.vchcenter.bean.Voucher; //import com.zephyr.vchcenter.util.test.XmlParseUtilTest;
import com.zephyr.vchcenter.bean.VoucherTemp;
import com.zephyr.vchcenter.bpm.util.RandomUtil;
import com.zephyr.vchcenter.dao.IBaseDao;
import com.zephyr.vchcenter.helper.SpringHelper;

public class XmlParseUtil {

	private static final Logger log = Logger.getLogger(XmlParseUtil.class);

	public List<Map<String, String>> parse(String xmlMsg)
			throws DocumentException {
		List<Map<String, String>> parseResult = new ArrayList<Map<String, String>>();
		Map<String, String> method = new HashMap<String, String>();
		Map<String, String> properties = new HashMap<String, String>();
		Document document = DocumentHelper.parseText(xmlMsg);
		Element rootElement = document.getRootElement();
		for (Iterator<Element> iterator = rootElement.elementIterator(); iterator
				.hasNext();) {
			Element element = iterator.next();
			if ("method".equals(element.getName())) {
				method.put("method", element.getText());
			} else {
				String propName = element.getName();
				properties.put(propName, element.getText());
			}
		}
		parseResult.add(method);
		parseResult.add(properties);
		return parseResult;
	}

	/**
	 * 验证印件信息
	 * 
	 * @param StampXML
	 *            印件信息报文
	 * @return 成功返回空,失败返回错误代码
	 */
	public static String verifyStampXML(String StampXML) {
		try {
			Document doc = DocumentHelper.parseText(StampXML);
			Node errnoNode = doc.getRootElement().selectSingleNode(
					"//error-code");
			String errno = errnoNode.getText().trim();
			Node errmsgNode = doc.getRootElement().selectSingleNode(
					"//error-msg");
			String errmsg = errmsgNode.getText().trim();
			if (!"000".equals(errno)) {
				return errno + errmsg;
			}
		} catch (Exception e) {
			log.debug(e.getMessage());
		}
		return "";

	}

	/**
	 * 组织2003获取印件报文
	 * 
	 * @param ip
	 *            客户端IP地址
	 * @param accno
	 *            账号
	 * @param type
	 *            印件类型（固定为：0）
	 * @param subno
	 *            分行号
	 * @param depno
	 *            网点号（提入行号）
	 * @return 2003交易报文
	 */
	public static String mark2003XML(String ip, Voucher vou, String type, String vchdate, String amount) {
		UUID sn = UUID.randomUUID();
		Document document = DocumentHelper.createDocument();
		Element resEl = document.addElement("response");
		Element seqEl = resEl.addElement("sequence");
		seqEl.setText("1001803809710");

		Element errEl = resEl.addElement("error");
		Element errCodeEl = errEl.addElement("error-code");
		errCodeEl.setText("000");
		Element errMsgEl = errEl.addElement("error-msg");
		errMsgEl.setText("成功");

		Element resultEl = resEl.addElement("result");
		Element zmsEl = resultEl.addElement("zms");

		Element reqEl = zmsEl.addElement("request");
		reqEl.addAttribute("appid", "cyclone");
		reqEl.addAttribute("moduleid", "2003");
		reqEl.addAttribute("sequence", sn.toString());
		reqEl.addAttribute("operateip", ip);
		reqEl.addAttribute("operateclkno", "99999");
		reqEl.addAttribute("warrantclkno", "");

		Element zkernelEl = zmsEl.addElement("zkernel");
		String subno = vou.getSubno();
		if(subno == null || "".equals(subno)) {
			subno = "";
		}
		String depno = vou.getBrbank();
		if(depno == null || "".equals(depno)) {
			depno = "";
		}
		zkernelEl.addAttribute("subno", subno);
		zkernelEl.addAttribute("depno", depno);

		Element sealEl = zmsEl.addElement("seal");
		sealEl.addAttribute("stampattr", "");
		String accno = vou.getAccno();
		if(accno == null || "".equals(accno)) {
			accno = "";
		}
		sealEl.addAttribute("accno", accno);
		if(type == null || "".equals(type)) {
			type = "";
		}
		sealEl.addAttribute("type", type);
		sealEl.addAttribute("enabledate", "");
		sealEl.addAttribute("stampno", "");
		sealEl.addAttribute("subno", "");
		sealEl.addAttribute("oldsubno", "");
		sealEl.addAttribute("depno", "");
		sealEl.addAttribute("olddepno", "");
		sealEl.addAttribute("state", "");
		sealEl.addAttribute("combflag", "");
		sealEl.addAttribute("buildclkno", "");
		sealEl.addAttribute("checkclkno", "");
		sealEl.addAttribute("newenabledate", "");

		Element vouEl = zmsEl.addElement("voucher");
		vouEl.addAttribute("vouchertype", "");
		if(amount == null || "".equals(amount)) {
			amount = "";
		}
		vouEl.addAttribute("amount", amount);
		vouEl.addAttribute("currency", "");
		vouEl.addAttribute("filename", "");
		if (vchdate != null && !"".equals(vchdate)) {
			vchdate = vchdate.replace("-", "");
		}
		if (vchdate == null || "".equals(vchdate)) {
			vchdate = "";
		}

		vouEl.addAttribute("voucherdate", vchdate);
		String xml = document.asXML();
		log.debug("2003XML: " + xml);
		return xml;
	}

	/**
	 * 组织运算交易报文
	 * 
	 * @param vou
	 *            票据对象
	 * @param zkernelXML
	 *            zkernel报文
	 * @param sealXML
	 *            seal报文
	 * @param image
	 *            图像base64编码格式
	 * @param scanflag
	 *            是否扫描标记
	 * @return 运算交易报文
	 * @throws DocumentException
	 * @throws SQLException
	 */
	@Deprecated
	public static String makeTradeXml(Voucher vou, String zkernelXML,
			String sealXML, String image, int scanflag)
			throws DocumentException, SQLException {

		String sysres = vou.getSysidres();
		if (sysres == null || "".equals(sysres)) {
			log.debug("sysres is null");
			sysres = "";
		}
		String combres = vou.getCombres();
		if (combres == null || "".equals(combres)) {
			log.debug("combres is null,set default value");
			combres = "0";
		}
		String finalres = vou.getIdresult();
		if (finalres == null || "".equals(finalres)) {
			log.debug("finalres is null,set default value");
			finalres = "0";
		}
		String mandetail = vou.getManstpres();
		if (mandetail == null || "".equals(mandetail)) {
			log.debug("mandetail is null");
			mandetail = "0";
		}
		String sysdetail = vou.getSysstpres();
		if (sysdetail == null || "".equals(sysdetail)) {
			log.debug("sysdetail is null");
			sysdetail = "0";
		}

		String vchtype = vou.getVchtype();
		if (vchtype == null || "".equals(vchtype)) {
			log.debug("vchtype is null");
			vchtype = "";
		}
		String amount = vou.getAmount();
		if (amount == null || "".equals(amount)) {
			log.debug("amount is null");
			amount = "";
		}

		String currency = vou.getMoneytype();
		if (currency == null || "".equals(currency)) {
			log.debug("currency is null");
			currency = "";
		}
		String fileName = "c:/tmp/tmp.jpg";

		String voucherdate = vou.getVchdate();
		if (voucherdate == null || "".equals(voucherdate)) {
			log.debug("voucherdate is null");
			voucherdate = "";
		} else {
			voucherdate = voucherdate.replace("-", "");
		}

		String img = image;
		if (img == null || "".equals(img)) {
			log.debug("img is null");
			img = "";
		}

		Object obj = SpringHelper.getBean("baseDao");
		IBaseDao baseDao = (IBaseDao) obj;
		ResultImage resImage = (ResultImage) baseDao.findById("ResultImage",
				vou.getVchsid());
		Blob idresImg = null;
		if (resImage != null && !"".equals(resImage)) {
			idresImg = resImage.getResimg();
		}

		String resImg = "";
		if (idresImg == null || "".equals(idresImg)) {
			log.debug("idresImg is null");
		} else {
			resImg = new String(idresImg.getBytes(new Long(1), Long.valueOf(
					idresImg.length()).intValue()));
		}

		String sFormat = new String();
		sFormat = String
				.format("<response><result><zms><return result=\"-1\" message=\"failure\"/>\n"
						+ zkernelXML
						+ sealXML
						+ "<idres sysres=\""
						+ sysres
						+ "\" combres=\""
						+ combres
						+ "\" finalres=\""
						+ finalres
						+ "\" mandetail=\""
						+ mandetail
						+ "\" sysdetail=\""
						+ sysdetail
						+ "\">"
						+ resImg
						+ "</idres><voucher vouchertype=\""
						+ vchtype
						+ "\" amount=\""
						+ amount
						+ "\" currency=\""
						+ currency
						+ "\" filename=\""
						+ fileName
						+ "\" voucherdate=\""
						+ voucherdate
						+ "\" >"
						+ img
						+ "</voucher><flagcollection scanflag=\""
						+ scanflag
						+ "\" reidentifyflag=\"1\" reservedone=\"\" reservedtwo=\"\"></flagcollection>\n</zms></result></response>");

		return sFormat;
	}

	/**
	 * 组织运算交易报文(dom4j实现)
	 * 
	 * @param vou
	 *            票据对象
	 * @param zkernelXML
	 *            zkernel报文
	 * @param sealXML
	 *            seal报文
	 * @param image
	 *            图像base64编码格式
	 * @param sceneflag
	 *            场景标记 0为核印经办 1为核印复核 2为本地扫描 3本地扫描复核
	 * @return 运算交易报文
	 * @throws DocumentException
	 * @throws SQLException
	 */
	public static String makeTradeDom4jXml(Voucher vou, String zkernelXML,
			String sealXML, String image, int sceneflag)
			throws DocumentException, SQLException {
		String sysres = vou.getSysidres();
		if (sysres == null || "".equals(sysres)) {
			log.debug("sysres is null");
			sysres = "";
		}
		String combres = vou.getCombres();
		if (combres == null || "".equals(combres)) {
			log.debug("combres is null,set default value");
			combres = "0";
		}
		String finalres = vou.getIdresult();
		if (finalres == null || "".equals(finalres)) {
			log.debug("finalres is null,set default value");
			finalres = "0";
		}
		String mandetail = vou.getManstpres();
		if (mandetail == null || "".equals(mandetail)) {
			log.debug("mandetail is null");
			mandetail = "0";
		}
		String sysdetail = vou.getSysstpres();
		if (sysdetail == null || "".equals(sysdetail)) {
			log.debug("sysdetail is null");
			sysdetail = "0";
		}

		String vchtype = vou.getVchtype();
		if (vchtype == null || "".equals(vchtype)) {
			log.debug("vchtype is null");
			vchtype = "";
		}
		String amount = vou.getAmount();
		if (amount == null || "".equals(amount)) {
			log.debug("amount is null");
			amount = "";
		}

		String currency = vou.getMoneytype();
		if (currency == null || "".equals(currency)) {
			log.debug("currency is null");
			currency = "";
		}
		String fileName = "c:/tmp/tmp.jpg";

		String voucherdate = vou.getVchdate();
		if (voucherdate == null || "".equals(voucherdate)) {
			log.debug("voucherdate is null");
			voucherdate = "";
		} else {
			voucherdate = voucherdate.replace("-", "");
		}

		String img = image;
		if (img == null || "".equals(img)) {
			log.debug("img is null");
			img = "";
		}

		Object obj = SpringHelper.getBean("baseDao");
		IBaseDao baseDao = (IBaseDao) obj;
		ResultImage resImage = (ResultImage) baseDao.findById("ResultImage",
				vou.getVchsid());
		Blob idresImg = null;
		if (resImage != null && !"".equals(resImage)) {
			idresImg = resImage.getResimg();
		}

		String resImg = "";
		if (idresImg == null || "".equals(idresImg)) {
			log.debug("idresImg is null");
		} else {
			resImg = new String(idresImg.getBytes(new Long(1), Long.valueOf(
					idresImg.length()).intValue()));
		}

		Document document = DocumentHelper.createDocument();
		Element resEl = document.addElement("response");
		Element resultEl = resEl.addElement("result");
		Element zmsEl = resultEl.addElement("zms");

		Element retEl = zmsEl.addElement("return");
		retEl.addAttribute("result", "-1");
		retEl.addAttribute("message", "failure");
		Element zkernelEl = DocumentHelper.parseText(zkernelXML)
				.getRootElement();
		zmsEl.add(zkernelEl);
		Element sealEl = DocumentHelper.parseText(sealXML).getRootElement();
		zmsEl.add(sealEl);

		Element idresEl = zmsEl.addElement("idres");
		idresEl.addAttribute("sysres", sysres);
		idresEl.addAttribute("combres", combres.toString());
		idresEl.addAttribute("finalres", finalres);
		idresEl.addAttribute("mandetail", mandetail.toString());
		idresEl.addAttribute("sysdetail", sysdetail);
		idresEl.setText(resImg);

		Element vouEl = zmsEl.addElement("voucher");
		vouEl.addAttribute("vouchertype", vchtype);
		vouEl.addAttribute("amount", amount);
		vouEl.addAttribute("currency", currency);
		vouEl.addAttribute("filename", fileName);
		vouEl.addAttribute("voucherdate", voucherdate);
		vouEl.setText(img);

		Element fcEl = zmsEl.addElement("flagcollection");
		String scanflag = "";
		String reidentifyflag = "";
	
		if(0 == sceneflag) {
			scanflag = "0";
			reidentifyflag = "1";
		}else if (1 ==sceneflag) {
			scanflag = "0";
			reidentifyflag = "0";
		}else if (2 == sceneflag) {
			scanflag = "1";
			reidentifyflag = "1";
		}else if (3 == sceneflag) {
			scanflag = "0";
			reidentifyflag = "0";
		}
		fcEl.addAttribute("scanflag", String.valueOf(scanflag));
		fcEl.addAttribute("reidentifyflag", String.valueOf(reidentifyflag));
		fcEl.addAttribute("reservedone", "");
		fcEl.addAttribute("reservedtwo", "");

		String xml = document.asXML();
		System.out.println(xml);
		return xml;
	}

	public static Voucher parse1006XML(Voucher voucher, String xml)
			throws DocumentException {
		Document document = DocumentHelper.parseText(xml);
		Node idresNode = document.selectSingleNode("//idres");
		voucher = idres2Voucher(voucher, idresNode);
		System.out.println(voucher.toString());
		return voucher;
	}

	public static List parse1015XML(Voucher voucher, String xml)
			throws DocumentException {
		Document document = DocumentHelper.parseText(xml);
		Node idresNode = document.selectSingleNode("//idres");
		voucher = idres2Voucher(voucher, idresNode);
		Node vouNode = document.selectSingleNode("//voucher");
		String vouImg = vouNode.getText();
		List list = new ArrayList();
		list.add(voucher);
		list.add(vouImg);
		System.out.println(list.toString());
		return list;
	}

	private static Voucher idres2Voucher(Voucher voucher, Node idresNode) {

		String idresImg = idresNode.getText();
		String sysres = idresNode.selectSingleNode("@sysres").getText();
		String combres = idresNode.selectSingleNode("@combres").getText();
		String finalres = idresNode.selectSingleNode("@finalres").getText();
		String mandetail = idresNode.selectSingleNode("@mandetail").getText();
		String sysdetail = idresNode.selectSingleNode("@sysdetail").getText();

		voucher.setSysidres(sysres);

		Object obj = SpringHelper.getBean("baseDao");
		IBaseDao baseDao = (IBaseDao) obj;
		ResultImage resImage = new ResultImage();
		resImage.setVchsid(voucher.getVchsid());
		resImage.setResimg((Blob) Hibernate.createBlob(idresImg.getBytes()));
		baseDao.saveOrUpdate(resImage);

		voucher.setIdresult(finalres);
		voucher.setSysstpres(sysdetail);
		voucher.setCombres(combres);
		voucher.setManstpres(mandetail);

		return voucher;
	}

	/**
	 * 返回XML中指定节点信息
	 * 
	 * @param xmlinfo
	 * @param node
	 *            指定节点
	 * @return 返回XML中指定节点信息
	 * @throws DocumentException
	 */
	public static String getNodeXML(String xmlinfo, String node)
			throws DocumentException {
		String result = "";
		Element root = DocumentHelper.parseText(xmlinfo).getRootElement();
		Node resNode = root.selectSingleNode("//" + node);

		return resNode.asXML();
	}

	/**
	 * 查找XML中的attribute value
	 * 
	 * @param MsgXML
	 *            结果XML报文
	 * @param MsgEl
	 *            结果XML的Element
	 * @param MsgAttr
	 *            结果XML的Attribute
	 * @return 返回attribute的值
	 * @throws DocumentException
	 */
	public static String exploreAttrValue(String MsgXML, String MsgEl,
			String MsgAttr) throws DocumentException {
		Document resultdoc = DocumentHelper.parseText(MsgXML);
		List list = resultdoc.selectNodes("//" + MsgEl + "/@" + MsgAttr);
		for (Iterator iter = list.iterator(); iter.hasNext();) {
			Attribute attribute = (Attribute) iter.next();
			return attribute.getValue();
		}
		return null;
	}

	// 解析批量扫描票据对象xml
	public static VoucherTemp getVouTmp4XML(String MsgXML)
			throws DocumentException {

		String accno = exploreAttrValue(MsgXML, "front", "accno");
		String vchno = exploreAttrValue(MsgXML, "front", "vchno");
		String vchtype = exploreAttrValue(MsgXML, "front", "vchtype");
		String money = exploreAttrValue(MsgXML, "front", "money");
		String exchno = exploreAttrValue(MsgXML, "front", "exchno");
		String vchdate = exploreAttrValue(MsgXML, "front", "vchdate");
		String fimgid = exploreAttrValue(MsgXML, "front", "imgid");
		String bimgid = exploreAttrValue(MsgXML, "back", "imgid");

		VoucherTemp vTmp = new VoucherTemp();
		RandomUtil randomUtil = new RandomUtil();
		vTmp.setVchsid(randomUtil.getUUID());
		vTmp.setAccno(accno);
		vTmp.setVchno(vchno);
		vTmp.setVchtype(vchtype);
		vTmp.setAmount(money);
		vTmp.setExchno(exchno);
		vTmp.setVchdate(vchdate);
		vTmp.setFimgid(fimgid);
		vTmp.setBimgid(bimgid);

		return vTmp;
	}

	public static String markImageServXML(String imgid, String img) {
		Element zmsEl = DocumentHelper.createDocument().addElement("zms");
		Element imageEl = zmsEl.addElement("image");
		imageEl.addAttribute("id", imgid);
		imageEl.setText(img);
		return zmsEl.asXML();
	}

	public static void main(String[] args) {

		// XmlParseUtil xmlParseUtil = new XmlParseUtil();
		/*
		 * String xmlMsg="<params><method>GetUnidentifyList</method><accno>123123213</accno><depno>0900</depno><vchno>092221</vchno></params>";
		 * try { List<Map<String, String>> list = xmlParseUtil.parse(xmlMsg);
		 * //assertEquals(2, list.size()); Map method=list.get(0);
		 * //assertEquals(1, method.size()); log.debug(method.get("method"));
		 * Map properties=list.get(1); //assertEquals(3, properties.size());
		 * log.debug(properties.get("accno"));
		 * log.debug(properties.get("depno"));
		 * log.debug(properties.get("vchno")); } catch (DocumentException e) {
		 * 
		 * log.error("����ʧ��"); }
		 */
		// System.out.println(xmlParseUtil.mark2003XML("127.0.0.1", "123123",
		// "1",
		// "123123", "0100"));
		// Voucher vou = new Voucher();
		// try {
		// System.out.println(makeTradeDom4jXml(vou, "<zkernel></zkernel>",
		// "<seal></seal>", "imgBase64...", 0));
		// } catch (DocumentException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		System.out.println(markImageServXML("aaa", "bbb"));
		// try {
		// parse1015XML(new Voucher(), "");
		// } catch (DocumentException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		/*
		 * try { makeTradeXml(new Voucher(), "<zkernel></zkernel>", "<seal></seal>",
		 * "", 0); } catch (DocumentException e) { // TODO Auto-generated catch
		 * block e.printStackTrace(); }
		 */

	}

}
